package com.party.web.biz.pay;

import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Maps;
import com.party.common.redis.StringJedis;
import com.party.common.utils.BigDecimalUtils;
import com.party.common.utils.DateUtils;
import com.party.core.model.YesNoStatus;
import com.party.core.model.charge.PackageMember;
import com.party.core.model.charge.ProductPackage;
import com.party.core.model.charge.ProductType;
import com.party.core.model.member.MemberGroup;
import com.party.core.model.member.MemberGroupInfo;
import com.party.core.model.member.PackageCount;
import com.party.core.model.order.*;
import com.party.core.model.partner.MemberPartner;
import com.party.core.model.system.*;
import com.party.core.service.charge.IPackageMemberService;
import com.party.core.service.charge.IPackageService;
import com.party.core.service.member.IMemberGroupInfoService;
import com.party.core.service.member.IMemberGroupService;
import com.party.core.service.member.IPackageCountService;
import com.party.core.service.notify.IInstanceService;
import com.party.core.service.order.IOrderFormService;
import com.party.core.service.order.IOrderTradeService;
import com.party.core.service.partner.IMemberPartnerService;
import com.party.core.service.partner.biz.MemberPartnerBizService;
import com.party.core.service.system.IMemberSysRoleService;
import com.party.core.service.system.ISysConfigService;
import com.party.core.service.system.ISysRoleService;
import com.party.notify.notifyPush.servce.INotifySendService;
import com.party.pay.model.pay.wechat.NotifyRequest;
import com.party.web.biz.charge.PackageBizService;
import com.party.web.web.security.SecurityRealm;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 支付业务处理
 */
@Service
public class PayPcOrderBizService {
    @Autowired
    private IOrderFormService orderFormService;
    @Autowired
    private IOrderTradeService orderTradeService;
    @Autowired
    private IPackageService packageService;
    @Autowired
    private IPackageMemberService packageMemberService;
    @Autowired
    private INotifySendService notifySendService;
    @Autowired
    private IMemberSysRoleService memberSysRoleService;
    @Autowired
    private IMemberGroupService memberGroupService;
    @Autowired
    private IPackageCountService packageCountService;
    @Autowired
    private ISysConfigService sysConfigService;
    @Autowired
    private IInstanceService instanceService;
    @Autowired
    private PackageBizService packageBizService;
    @Autowired
    private IMemberPartnerService memberPartnerService;
    @Autowired
    private ISysRoleService sysRoleService;
    @Autowired
    private IMemberGroupInfoService memberGroupInfoService;
    @Autowired
    private StringJedis stringJedis;
    @Autowired
    private MemberPartnerBizService memberPartnerBizService;

    protected static Logger logger = LoggerFactory.getLogger(PayPcOrderBizService.class);

    /**
     * 支付回调处理业务
     *
     * @param orderForm  订单
     * @param data       支付流水
     * @param paymentWay 支付方式
     * @throws Exception
     */
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void updatePayBusiness(OrderForm orderForm, Object data, Integer paymentWay) throws Exception {
        logger.info("支付回调处理业务——" + orderForm);
        // 修改订单状态
        orderForm.setIsPay(PaymentState.IS_PAY.getCode());
        orderForm.setPaymentWay(paymentWay);
        orderForm.setStatus(OrderStatus.ORDER_STATUS_HAVE_PAID.getCode());
        orderFormService.update(orderForm);

        // 保存支付流水
        saveOrderTrade(orderForm, data, paymentWay);

        // 保存用户等级 更改用户角色
        saveLevelMember(orderForm.getGoodsId(), orderForm.getMemberId(), orderForm.getId());

        try {
            notifySendService.sendBuyLevel(orderForm.getMemberId(), orderForm.getTitle(), orderForm.getPhone());
        } catch (Exception e) {
            logger.error("扫码支付回调消息推送异常", e);
        }

        try {
            ProductPackage productPackage = packageService.get(orderForm.getGoodsId());
            if (productPackage.getType().equals(ProductType.MODULE_TYPE.getCode())
                    || productPackage.getType().equals(ProductType.PACKAGE_TYPE.getCode())

            ) {
                SecurityRealm.reloadAuthorizing(orderForm.getMemberId());
            }
        } catch (Exception e) {
            logger.error("模块或者套餐购买完成后刷新权限异常", e);
        }
    }

    /**
     * 保存用户等级 更改用户角色
     *
     * @param packageId 套餐id
     * @param memberId  用户id
     */
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void saveLevelMember(String packageId, String memberId, String orderId) throws Exception {
        ProductPackage productPackage = packageService.get(packageId);
        if (productPackage != null) {
            if (productPackage.getType().equals(ProductType.SMS_PACKAGE_TYPE.getCode())) { // 短信套餐，保存数量
                PackageCount packageCount = new PackageCount(memberId, TargetType.PUSH_SMS.getCode());
                if (productPackage.getPrice() > Float.valueOf(0.0f)) { // 收费
                    PackageMember packageMember = packageMemberService.findByOrderId(orderId);
                    packageMember.setStatus(1);
                    packageMember.setPayStatus(2); // 更改支付状态
                    packageMemberService.update(packageMember);

                    packageCount.setQuantity(packageMember.getQuantity());
                } else { // 免费
                    PackageMember packageMember = new PackageMember();
                    packageMember.setQuantity(productPackage.getQuantity());
                    packageMember.setStatus(1);
                    packageMember.setPayStatus(2); // 付款状态 已支付
                    packageMember.setLevelId(packageId);
                    packageMember.setMemberId(memberId);
                    packageMember.setPrice(0f);
                    packageMember.setPackageName(productPackage.getName());
                    packageMember.setSmsSource(1);
                    packageMemberService.insert(packageMember);

                    packageCount.setQuantity(productPackage.getQuantity());
                }
                savePackageCountBiz(packageCount);
            } else if (productPackage.getType().equals(ProductType.PACKAGE_TYPE.getCode())
                    || productPackage.getType().equals(ProductType.MODULE_TYPE.getCode())) { // 套餐、模块，保存用户等级，更改用户角色
                if (productPackage.getPrice() > Float.valueOf(0.0f)) { // 收费
                    PackageMember packageMember = packageMemberService.findByOrderId(orderId);
                    packageMember.setStatus(1);
                    packageMember.setPayStatus(2); // 更改支付状态
                    packageMemberService.update(packageMember);
                } else {
                    Map<String, Date> resultMap = packageBizService.calculateDate(productPackage, null);
                    Date startTime = resultMap.get("startTime");
                    Date endTime = resultMap.get("endTime");
                    PackageMember packageMember = new PackageMember();
                    packageMember.setStatus(1);
                    packageMember.setPayStatus(2); // 付款状态 已支付
                    packageMember.setLevelId(packageId);
                    packageMember.setMemberId(memberId);
                    packageMember.setPrice(0f);
                    packageMember.setPackageName(productPackage.getName());
                    packageMember.setStartTime(startTime);
                    packageMember.setEndTime(endTime);
                    packageMember.setSysRoleId(productPackage.getSysRoleId());
                    packageMemberService.insert(packageMember);
                }
                List<MemberSysRole> roles = memberSysRoleService.list(new MemberSysRole(memberId, productPackage.getSysRoleId()));
                if (roles.size() == 0) {
                    MemberSysRole sysRole = new MemberSysRole();
                    sysRole.setMemberId(memberId);
                    sysRole.setRoleId(productPackage.getSysRoleId());
                    memberSysRoleService.insert(sysRole);
                }
            } else if (ProductType.SYSTEM_TYPE.getCode() == productPackage.getType()) { //系统购买
                PackageMember packageMember = packageMemberService.findByOrderId(orderId);
                MemberPartner mpOrg = memberPartnerService.findByMemberId(memberId);
                MemberGroupInfo memberGroupInfo = memberGroupInfoService.findByMemberId(memberId);

                logger.info("系统购买————初始值 ——packageMember" + packageMember);
                logger.info("系统购买————初始值 ——MemberPartner" + mpOrg);
                logger.info("系统购买————初始值 ——memberGroupInfo" + memberGroupInfo);

                packageMember.setPayStatus(2); // 更改支付状态

                if (null == mpOrg.getSystemType() || 0 == mpOrg.getSystemType()) { //第一次购买

                    //设置当前系统类型
                    mpOrg.setSystemType(productPackage.getSystemType());
                    String roleCode = "";

                    //分配系统套餐角色-----众筹系统
                    if (ProductPackage.SYSTEM_TYPE_ZC == productPackage.getSystemType()) {
                        roleCode = RoleEnum.PARTNER_2_ROLE.getCode();
                    }
                    //分配系统套餐角色-----社群系统
                    if (ProductPackage.SYSTEM_TYPE_SQ == productPackage.getSystemType()) {
                        roleCode = RoleEnum.COMMUNITY__ROLE.getCode();
                    }

                    Integer roleType = RoleType.PARTNER_ROLE.getCode();
                    SysRole sysRole = sysRoleService.getRole(roleCode, roleType);

                    MemberSysRole memberSysRole = new MemberSysRole(memberId, sysRole.getId());
                    memberSysRoleService.insert(memberSysRole);

                    //处理系统到期时间
                    memberGroupInfo.setExpirationTime(packageMember.getEndTime());


                } else {  //再次购买

                    if (DateUtils.compareDate(memberGroupInfo.getExpirationTime(), new Date()) == 1) {  //未到期

                        if (productPackage.getSystemType() == mpOrg.getSystemType()) {  //续费

                            List<PackageMember> packageMemberList = packageMemberService.getLatelyPaySuccess(memberId);
                            if (packageMemberList.size() < 1) {
                                //admin 添加的客户
                                //累加后的到期时间
                                Date newEndDate = DateUtils.addMonth(memberGroupInfo.getExpirationTime(),
                                        DateUtils.getMonth(packageMember.getStartTime(), packageMember.getEndTime()));

                                memberGroupInfo.setExpirationTime(newEndDate);
                            } else {
                                //累加后的到期时间
                                memberGroupInfo.setExpirationTime(packageMember.getEndTime());
                            }
                        } else if (ProductPackage.SYSTEM_TYPE_SQ == mpOrg.getSystemType()
                                && ProductPackage.SYSTEM_TYPE_ZC == productPackage.getSystemType()) {  //升级

                            //分配系统套餐角色-----众筹系统
                            SysRole sysRole = sysRoleService.getRole(RoleEnum.PARTNER_2_ROLE.getCode(),
                                    RoleType.PARTNER_ROLE.getCode());
                            MemberSysRole memberSysRole = new MemberSysRole(memberId, sysRole.getId());
                            memberSysRoleService.insert(memberSysRole);

                            //累加后的到期时间
/*                            Date newEndDate = DateUtils.addMonth(new Date(),
                                    DateUtils.getMonth(packageMember.getStartTime(), packageMember.getEndTime()));

                            memberGroupInfo.setExpirationTime(newEndDate);*/

                            //设置当前系统类型
                            mpOrg.setSystemType(productPackage.getSystemType());
                        }
                    } else { //已到期

                        if (productPackage.getSystemType() == mpOrg.getSystemType()) { //续费
                            //累加后的到期时间
                            Date newEndDate = DateUtils.addMonth(new Date(),
                                    DateUtils.getMonth(packageMember.getStartTime(), packageMember.getEndTime()));

                            memberGroupInfo.setExpirationTime(newEndDate);
                        } else {
                            if (ProductPackage.SYSTEM_TYPE_SQ == mpOrg.getSystemType()
                                    && ProductPackage.SYSTEM_TYPE_ZC == productPackage.getSystemType()) { //升级

                                //分配系统套餐角色-----众筹系统
                                SysRole sysRole = sysRoleService.getRole(RoleEnum.PARTNER_2_ROLE.getCode(),
                                        RoleType.PARTNER_ROLE.getCode());
                                MemberSysRole memberSysRole = new MemberSysRole(memberId, sysRole.getId());
                                memberSysRoleService.insert(memberSysRole);

                            } else if (ProductPackage.SYSTEM_TYPE_ZC == mpOrg.getSystemType()
                                    && ProductPackage.SYSTEM_TYPE_SQ == productPackage.getSystemType()) { //降级
                                //删除该用户所有的套餐角色，重新分配一个社群角色

                                //注：因系统到期时间是和用户一对一关联的，没有和套餐角色关联,
                                // 故删除其他角色后将失去原来的功能菜单，只有当前的社群角色功能菜单
                                HashMap<String, Object> mmp = Maps.newHashMap();
                                mmp.put("memberId", memberId);
                                List<MemberSysRole> memberSysRoles = memberSysRoleService.queryMemberRoleAll(RoleType.PARTNER_ROLE.getCode(), mmp);
                                for (MemberSysRole msr : memberSysRoles) {
                                    logger.info("降级刪除的角色 ：" + msr);
                                    memberSysRoleService.deleteByRoleIdAndMemberId(msr.getRoleId(), msr.getMemberId());
                                }
                                SysRole sysRole = sysRoleService.getRole(RoleEnum.COMMUNITY__ROLE.getCode(),
                                        RoleType.PARTNER_ROLE.getCode());
                                MemberSysRole memberSysRole = new MemberSysRole(memberId, sysRole.getId());
                                memberSysRoleService.insert(memberSysRole);
                            }
                            //累加后的到期时间
                            Date newEndDate = DateUtils.addMonth(new Date(),
                                    DateUtils.getMonth(packageMember.getStartTime(), packageMember.getEndTime()));

                            memberGroupInfo.setExpirationTime(newEndDate);
                            //设置当前系统类型
                            mpOrg.setSystemType(productPackage.getSystemType());
                        }
                    }
                }

                packageMemberService.update(packageMember);
                memberPartnerService.update(mpOrg);
                memberGroupInfoService.update(memberGroupInfo);

                memberPartnerBizService.saveOrUpdateChildMemberPartner(mpOrg);

                try {
                    String key = "EXPIRE_DATE_" + mpOrg.getMemberId();
                    stringJedis.setValue(key, DateUtils.formatDate(memberGroupInfo.getExpirationTime(), "yyyy-MM-dd HH:mm:ss"));
                    logger.info("系统购买————log8");
                } catch (Exception e) {
                    logger.error("redis 设置 key--{}过期时间异常", "EXPIRE_DATE_" + mpOrg.getMemberId(), e);
                }

                logger.info("系统购买————修改后的值 ——packageMember" + packageMember);
                logger.info("系统购买————修改后的值 ——MemberPartner" + mpOrg);
                logger.info("系统购买————修改后的值 ——memberGroupInfo" + memberGroupInfo);
            }
        }
    }

    /**
     * 免费模块购买
     *
     * @param packageId 模块id
     * @param memberId  用户id
     */
    public void freeUpdateBusiness(String packageId, String memberId) throws Exception {
        // 保存用户等级 更改用户角色
        saveLevelMember(packageId, memberId, "");

        MemberGroup member = memberGroupService.get(memberId);
        ProductPackage productPackage = packageService.get(packageId);

        String title = packageBizService.appendTitle(productPackage, null);
        notifySendService.sendBuyLevel(memberId, title, member.getMobile());

        SecurityRealm.reloadAuthorizing(memberId);
    }

    /**
     * 持久化交易信息
     *
     * @param orderForm  订单信息
     * @param object     支付信息
     * @param paymentWay 支付方式
     */
    public void saveOrderTrade(OrderForm orderForm, Object object, Integer paymentWay) {
        OrderForm t = orderFormService.get(orderForm.getId());

        // 持久化交易信息
        OrderTrade orderTrade = new OrderTrade();
        orderTrade.setOrderFormId(orderForm.getId());

        orderTrade.setOrigin(OrderOrigin.ORDER_ORIGIN_LEVEL.getCode());

        // 判断支付方式
        if (PaymentWay.ALI_PAY.getCode().equals(paymentWay)) {
            Map<String, String> params = (Map<String, String>) object;
            orderTrade.setType(PaymentWay.ALI_PAY.getCode());
            orderTrade.setTransactionId(params.get("trade_no"));
            orderTrade.setData(JSONObject.toJSONString(params));
            t.setPayment(Float.valueOf(params.get("total_amount")));
            t.setTradeState(params.get("trade_status"));
            t.setTransactionId(params.get("trade_no"));
            orderFormService.update(t);
        } else if (PaymentWay.WECHAT_PAY.getCode().equals(paymentWay)) {
            NotifyRequest notifyRequest = (NotifyRequest) object;
            orderTrade.setTransactionId(notifyRequest.getTransactionId());
            orderTrade.setType(PaymentWay.WECHAT_PAY.getCode());
            orderTrade.setData(JSONObject.toJSONString(notifyRequest));
            double price = BigDecimalUtils.div(Double.valueOf(notifyRequest.getTotalFee()), 100);
            t.setPayment((float) price);
            t.setMerchantId(notifyRequest.getMchId());
            t.setTradeState(notifyRequest.getResultCode());
            t.setTransactionId(notifyRequest.getTransactionId());
            orderFormService.update(t);
        }
        orderTradeService.insert(orderTrade);
    }

    /**
     * 用户套餐使用控制保存
     *
     * @param pc
     */
    @Transactional
    public void savePackageCountBiz(PackageCount pc) throws Exception {
        String memberId = pc.getMemberId();
        String type = pc.getType();
        Integer quantity = pc.getQuantity();
        if (StringUtils.isNotEmpty(memberId) && StringUtils.isNotEmpty(type)) {
            PackageCount packageCount = packageCountService.getUnique(new PackageCount(memberId, type));
            if (packageCount == null) {
                // 短信预警默认配置
                SysConfig smsWarnConfig = sysConfigService.findByCode(PackageCount.SMS_WARN_NUM_DEFAULT);
                // 短信超出使用默认配置
                SysConfig smsExcessConfig = sysConfigService.findByCode(PackageCount.SMS_EXCESS_NUM_DEFAULT);

                packageCount = new PackageCount(memberId, type);
                packageCount.setIsOpen(YesNoStatus.NO_NEW.getCode()); // 默认关闭
                packageCount.setIsAllowExcess(YesNoStatus.NO_NEW.getCode()); // 默认关闭
                if (smsWarnConfig != null) {
                    packageCount.setWarnNum(Integer.valueOf(smsWarnConfig.getValue()));
                } else {
                    packageCount.setWarnNum(0);
                }
                if (smsExcessConfig != null) {
                    packageCount.setExcessNum(Integer.valueOf(smsExcessConfig.getValue()));
                } else {
                    packageCount.setExcessNum(0);
                }
                packageCount.setTotalNum(0);
                packageCount.setUseNum(0);
            }
            if (quantity != null) {
                packageCount.setTotalNum(packageCount.getTotalNum() + quantity);
                Integer useNum = instanceService.getSmsSendSuccess(memberId);
                packageCount.setUseNum(useNum);

                Integer tempTotalNum = packageCount.getTotalNum() - packageCount.getUseNum();
                packageCount.setTempTotalNum(tempTotalNum);
            }
            if (packageCount.getTotalNum() - packageCount.getUseNum() > 0) {
                packageCount.setIsWarned(YesNoStatus.NO_NEW.getCode());
            }
            packageCount.setUpdateBy(memberId);
            if (StringUtils.isEmpty(packageCount.getId())) {
                packageCountService.insert(packageCount);
            } else {
                if (quantity == null) {
                    packageCount.setWarnNum(pc.getWarnNum());
                }
                packageCountService.update(packageCount);
            }
        }
    }
}
